import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import font_manager

# 设置字体为 SimHei（黑体），确保该字体已安装
plt.rcParams['font.family'] = 'SimHei'  # 中文显示
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 读取爬取到的 JSON 文件
df = pd.read_json(r'D:\网络爬虫\douban\movies.json')

# 获取数据总条数
total_movies = df.shape[0]
print(f"总电影数量: {total_movies}")

# 处理评分数据
df['rating'] = pd.to_numeric(df['rating'], errors='coerce')
df = df[df['rating'].notna()]

# 统计每个评分的电影数量
rating_counts = df['rating'].value_counts().sort_index()

# 绘制评分直方图
plt.figure(figsize=(12, 6))
colors = sns.color_palette("husl", len(rating_counts))  # 选择不同的颜色
plt.bar(rating_counts.index, rating_counts.values, width=0.1, color=colors)
plt.title('豆瓣电影评分分布', fontsize=16)
plt.xlabel('评分', fontsize=14)
plt.ylabel('电影数量', fontsize=14)
plt.xticks(rating_counts.index)
plt.grid(axis='y', linestyle='--', alpha=0.7)
for i in range(len(rating_counts)):
    plt.text(rating_counts.index[i], rating_counts.values[i],
             f'{rating_counts.values[i]}', ha='center', va='bottom', fontsize=12)
plt.show()

# 统计分析
mean_rating = df['rating'].mean()
median_rating = df['rating'].median()
std_rating = df['rating'].std()

print(f"平均评分: {mean_rating:.2f}")
print(f"中位数评分: {median_rating:.2f}")
print(f"评分标准差: {std_rating:.2f}")

# 绘制评分饼图
rating_bins = [0, 5, 7, 9, 10]
rating_labels = ['低评分 (0-5)', '中评分 (5-7)', '高评分 (7-9)', '超高评分 (9-10)']
df['rating_category'] = pd.cut(df['rating'], bins=rating_bins, labels=rating_labels, right=False)

category_counts = df['rating_category'].value_counts()

# 绘制评分类别饼图
plt.figure(figsize=(10, 10))
pie_colors = sns.color_palette("pastel", len(category_counts))
plt.pie(category_counts, labels=category_counts.index, autopct='%1.1f%%', startangle=140, colors=pie_colors)
plt.title('豆瓣电影评分类别分布', fontsize=16)
plt.axis('equal')
plt.show()

# 绘制热力图
heatmap_data = df.pivot_table(index='rating_category', values='title', aggfunc='count')

plt.figure(figsize=(10, 6))
sns.heatmap(heatmap_data, annot=True, fmt='g', cmap='YlGnBu', cbar=True)
plt.title('豆瓣电影评分类别热力图', fontsize=16)
plt.xlabel('电影数量', fontsize=14)
plt.ylabel('评分类别', fontsize=14)
plt.show()

# 绘制密度分布图
plt.figure(figsize=(12, 6))
sns.kdeplot(df['rating'], fill=True, color='skyblue', alpha=0.5, bw_adjust=0.5)
plt.title('豆瓣电影评分密度分布图', fontsize=16)
plt.xlabel('评分', fontsize=14)
plt.ylabel('密度', fontsize=14)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()

# 处理电影年份数据
df['year'] = pd.to_numeric(df['year'], errors='coerce')  # 确保年份是数值类型
df = df[df['year'].notna()]  # 去除缺失值

# 定义年份区间，比如每10年一个区间
year_bins = [1900, 1960, 1970, 1980, 1990, 2000, 2010, 2020, 2030]  # 注意最后一个区间设为未来年份以包含所有可能的数据
year_labels = ['1900-1959', '1960-1969', '1970-1979', '1980-1989', '1990-1999', '2000-2009', '2010-2019', '2020-2029']

# 对年份进行分组
df['year_category'] = pd.cut(df['year'], bins=year_bins, labels=year_labels, right=False)

# 统计每个年份区间的电影数量
year_category_counts = df['year_category'].value_counts().sort_index()

# 绘制年份区间直方图
plt.figure(figsize=(12, 6))
plt.bar(year_category_counts.index, year_category_counts.values, color='skyblue')
plt.title('豆瓣电影年份区间分布', fontsize=16)
plt.xlabel('年份区间', fontsize=14)
plt.ylabel('电影数量', fontsize=14)
plt.xticks(rotation=45)  # 旋转x轴标签以便更好地显示
plt.grid(axis='y', linestyle='--', alpha=0.7)
for i in range(len(year_category_counts)):
    plt.text(year_category_counts.index[i], year_category_counts.values[i],
             f'{year_category_counts.values[i]}', ha='center', va='bottom', fontsize=12)
plt.show()